package org.example.service.impl;


import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpStatus;
import com.alibaba.nacos.api.utils.StringUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.http.entity.ContentType;
import org.aspectj.util.FileUtil;
import org.example.dao.ApiHistoryRepository;
import org.example.dao.ApiKeyRepository;
import org.example.dao.FileInfoRepository;
import org.example.entity.*;
import org.example.feign.ApiFeign;
import org.example.service.ApiService;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.ExecutorService;

@Service
public class ApiServiceImpl implements ApiService {

	@Resource
	private ApiFeign apiFeign;
	@Resource
	private ApiKeyRepository apiKeyRepository;

	@Resource
	private BASE64Encoder base64Encoder;
	@Resource
	private ExecutorService executorService;


	@Resource
	private FileInfoRepository fileInfoRepository;
	@Resource
	private ApiHistoryRepository apiHistoryRepository;


	@Override
	public CommonResult<Void> api(String apiKey, final MultipartFile file) {

		ApiKey byKeyAndUserId = this.apiKeyRepository.findByKey(apiKey);
		if (byKeyAndUserId != null) {
			final ApiHistory apiHistory = new ApiHistory();
			apiHistory.setUid(byKeyAndUserId.getUserId());
			apiHistory.setStatus("待处理");
			this.apiHistoryRepository.save(apiHistory);
			byte[] bytes = null;

			{
				try {
					bytes = FileUtil.readAsByteArray(file.getInputStream());
				} catch (IOException ignored) {
				}
			}
			final byte[] finalBytes = bytes;
			this.executorService.submit(new Runnable() {


				@Override
				public void run() {
					apiHistory.setStatus("处理中");
					apiHistoryRepository.save(apiHistory);
					InputStream outputFileStream = null;
					ByteArrayInputStream byteArrayInputStream = null;
					try {
						if (finalBytes == null) {
							throw new RuntimeException("文件为空");
						}
						byteArrayInputStream = new ByteArrayInputStream(finalBytes);
						MultipartFile mockMultipartFile = new MockMultipartFile(ContentType.APPLICATION_OCTET_STREAM.toString(),
								byteArrayInputStream);
						outputFileStream = apiFeign.upload(mockMultipartFile).body().asInputStream();
						apiHistory.setInputFileId(saveFile(finalBytes, file.getOriginalFilename()));
						apiHistory.setOutputFileId(saveFile(outputFileStream, IdUtil.simpleUUID() + "."
								+ FileNameUtil.extName(file.getOriginalFilename())));


					} catch (IOException e) {
						throw new RuntimeException(e);
					} finally {
						if (!StringUtils.isEmpty(apiHistory.getInputFileId()) &&
								!StringUtils.isEmpty(apiHistory.getOutputFileId())) {
							apiHistory.setStatus("处理完成");
						} else {
							apiHistory.setStatus("处理失败");
						}
						apiHistoryRepository.save(apiHistory);

						try {
							if (outputFileStream != null) {
								outputFileStream.close();
							}
						} catch (IOException ignored) {
						}
						try {
							if (byteArrayInputStream != null) {
								byteArrayInputStream.close();
							}
						} catch (IOException ignored) {
						}
					}
				}
			});


			return new CommonResult<>(HttpStatus.HTTP_OK, "调用成功，请耐心等待处理");
		}
		return new CommonResult<>(HttpStatus.HTTP_UNAUTHORIZED, "认证失败");
	}

	@Override
	public CommonResult<String> getKey() {
		LoginUser principal = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		final Integer id = principal.getCommonUserInfo().getId();
		ApiKey byUserId = this.apiKeyRepository.findByUserId(id);
		if (byUserId == null) {
			updateKey();
			byUserId = this.apiKeyRepository.findByUserId(id);
		}
		return new CommonResult<>(HttpStatus.HTTP_OK, "获取成功", byUserId.getKey());
	}

	@Override
	public CommonResult<String> updateKey() {
		LoginUser principal = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		final Integer id = principal.getCommonUserInfo().getId();
		ApiKey byUserId = this.apiKeyRepository.findByUserId(id);
		if (byUserId == null) {
			byUserId = new ApiKey();
			byUserId.setUserId(id);
		}
		byUserId.setKey(RandomStringUtils.randomAlphanumeric(32));
		this.apiKeyRepository.save(byUserId);
		return new CommonResult<>(HttpStatus.HTTP_OK, "更新成功", byUserId.getKey());
	}

	@Override
	public CommonResult<List<ApiHistory>> getHistory() {
		LoginUser principal = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		final Integer id = principal.getCommonUserInfo().getId();
		return new CommonResult<>(HttpStatus.HTTP_OK, "查询成功", this.apiHistoryRepository.findAllByUid(id));
	}

	@Override
	public void downloadFile(String fileId, HttpServletResponse httpResponse) throws IOException {
		FileInfo byIdIs = this.fileInfoRepository.findByIdIs(fileId);
		if (byIdIs != null && byIdIs.getBytes() != null) {
			httpResponse.setHeader("Content-Disposition", "attachment;filename=" + byIdIs.getFileName());

			httpResponse.getOutputStream().write(byIdIs.getBytes());
		}
	}

	public String saveFile(InputStream inputStream, String fileName) throws IOException {
		FileInfo fileInfo = new FileInfo(null, FileUtil.readAsByteArray(inputStream), fileName);
		fileInfoRepository.save(fileInfo);
		return fileInfo.getId();
	}

	public String saveFile(byte[] bytes, String fileName) {
		FileInfo fileInfo = new FileInfo(null, bytes, fileName);
		fileInfoRepository.save(fileInfo);
		return fileInfo.getId();
	}

}